﻿using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace 寻路径算法
{
    public partial class MainWindow : Window
    {
        private readonly Graph _graph = new Graph();
        private readonly Dictionary<Node, UIElement> _nodeVisuals = new Dictionary<Node, UIElement>();
        private int _nodeCounter = 0;

        public MainWindow()
        {
            InitializeComponent();
            InitializeSampleGraph();
        }

        private void InitializeSampleGraph()
        {
            var start1 = new Node("Start_1", NodeType.Start, 100, 100);
            var proc1 = new Node("Proc_1", NodeType.Process, 300, 100);
            var proc2 = new Node("Proc_2", NodeType.Process, 500, 100);
            var exec1 = new Node("Exec_1", NodeType.Executive, 300, 250);
            var exec2 = new Node("Exec_2", NodeType.Executive, 500, 250);
            var proc4 = new Node("Proc_4", NodeType.Process, 500, 400);
            var end1 = new Node("End_1", NodeType.End, 700, 250);
            var end2 = new Node("End_2", NodeType.End, 700, 400);

            foreach (var node in new[] { start1, proc1, proc2, exec1, exec2, proc4, end1, end2 })
            {
                _graph.AddNode(node);
                DrawNode(node);
            }

            // 使用新的端口获取方式，通过名称区分
            var edges = new[]
            {
                new Edge(start1.GetPort("Output"), proc1.GetPort("Input")),
                new Edge(proc1.GetPort("Output"), proc2.GetPort("Input")),
                new Edge(proc2.GetPort("Output"), exec2.GetPort("Input")),
                new Edge(exec2.GetPort("Output"), end2.GetPort("Input")),

                new Edge(start1.GetPort("Output"), exec1.GetPort("Input")),
                new Edge(exec1.GetPort("Output"), proc4.GetPort("Input")),
                new Edge(proc4.GetPort("Output"), end1.GetPort("Input")),

                new Edge(proc1.GetPort("Output"), exec1.GetPort("Input")),
                new Edge(exec1.GetPort("Output"), end1.GetPort("Input"))
            };

            foreach (var edge in edges)
            {
                _graph.AddEdge(edge);
                DrawEdge(edge);
            }
        }

        private void DrawNode(Node node)
        {
            const double width = 100.0;
            const double height = 60.0;

            var rect = new Rectangle
            {
                Width = width,
                Height = height,
                Stroke = Brushes.Black,
                StrokeThickness = 2,
                Fill = GetNodeColor(node.Type)
            };

            var text = new TextBlock
            {
                Text = $"{node.Id}\n({node.Type})",
                TextAlignment = TextAlignment.Center,
                VerticalAlignment = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center,
                Margin = new Thickness(5)
            };

            var grid = new Grid();
            grid.Children.Add(rect);
            grid.Children.Add(text);

            Canvas.SetLeft(grid, node.X - width / 2);
            Canvas.SetTop(grid, node.Y - height / 2);

            GraphCanvas.Children.Add(grid);
            _nodeVisuals[node] = grid;

            GraphCanvas.Width = Math.Max(GraphCanvas.Width, node.X + width);
            GraphCanvas.Height = Math.Max(GraphCanvas.Height, node.Y + height);
        }

        private Brush GetNodeColor(NodeType type)
        {
            return type switch
            {
                NodeType.Start => Brushes.LightGreen,
                NodeType.End => Brushes.LightBlue,
                NodeType.Executive => Brushes.Orange,
                NodeType.Process => Brushes.LightYellow,
                _ => Brushes.White
            };
        }

        private void DrawEdge(Edge edge)
        {
            var fromPos = edge.FromNode.GetPortAbsolutePosition(edge.FromPort);
            var toPos = edge.ToNode.GetPortAbsolutePosition(edge.ToPort);

            var line = new Line
            {
                X1 = fromPos.X,
                Y1 = fromPos.Y,
                X2 = toPos.X,
                Y2 = toPos.Y,
                Stroke = Brushes.Gray,
                StrokeThickness = 2
            };

            GraphCanvas.Children.Add(line);
        }

        private void FindAnyExecutivePath_Click(object sender, RoutedEventArgs e)
        {
            var nodes = _graph.Nodes.ToList();
            var startNodes = nodes.Where(n => n.Type == NodeType.Start).ToList();
            var endNodes = nodes.Where(n => n.Type == NodeType.End).ToList();

            var allValidPaths = new List<List<Node>>();

            foreach (var start in startNodes)
            {
                foreach (var end in endNodes)
                {
                    var paths = _graph.FindAllPathsDFS(start, end);
                    foreach (var path in paths)
                    {
                        if (path.Count > 1 && path.Any(n => n.Type == NodeType.Executive))
                        {
                            allValidPaths.Add(path);
                        }
                    }
                }
            }

            if (allValidPaths.Any())
            {
                var pathTexts = allValidPaths.Select((path, index) =>
                    $"路径 {index + 1}:\n" + string.Join(" → ", path.Select(n => $"{n.Id}({n.Type})"))
                );

                PathResultTextBox.Text = "✅ 找到以下完整有效路径（Start → End 且含 Executive）：\n\n" +
                                        string.Join("\n\n", pathTexts);

                HighlightAllPaths(allValidPaths);
                return;
            }

            var anyValidPaths = new List<List<Node>>();
            foreach (var start in nodes)
            {
                foreach (var end in nodes)
                {
                    if (start == end) continue;

                    var paths = _graph.FindAllPathsDFS(start, end);
                    foreach (var path in paths)
                    {
                        if (path.Count > 1 && path.Any(n => n.Type == NodeType.Executive))
                        {
                            anyValidPaths.Add(path);
                        }
                    }
                }
            }

            if (anyValidPaths.Any())
            {
                var pathTexts = anyValidPaths.Select((path, index) =>
                    $"路径 {index + 1}:\n" + string.Join(" → ", path.Select(n => $"{n.Id}({n.Type})"))
                );

                PathResultTextBox.Text = "⚠️ 找到以下部分有效路径（含 Executive，但非 Start→End）：\n\n" +
                                        string.Join("\n\n", pathTexts);

                HighlightAllPaths(anyValidPaths);
                return;
            }

            PathResultTextBox.Text = "❌ 未找到包含执行元件的有效路径！";
            ClearHighlights();
        }

        private void HighlightAllPaths(List<List<Node>> allPaths)
        {
            ClearHighlights(false);

            var allNodesInPaths = new HashSet<Node>();
            var allEdgesInPaths = new HashSet<Edge>();

            foreach (var path in allPaths)
            {
                for (int i = 0; i < path.Count; i++)
                {
                    allNodesInPaths.Add(path[i]);

                    if (i < path.Count - 1)
                    {
                        var fromNode = path[i];
                        var toNode = path[i + 1];

                        var edge = _graph.Edges.FirstOrDefault(e =>
                            e.FromNode == fromNode && e.ToNode == toNode);

                        if (edge != null)
                        {
                            allEdgesInPaths.Add(edge);
                        }
                    }
                }
            }

            foreach (var node in allNodesInPaths)
            {
                if (_nodeVisuals.TryGetValue(node, out var visual) && visual is Grid grid && grid.Children[0] is Shape shape)
                {
                    shape.Stroke = Brushes.Red;
                    shape.StrokeThickness = 4;

                    if (node.Type == NodeType.Executive)
                    {
                        shape.Fill = Brushes.DarkOrange;
                    }
                    else
                    {
                        shape.Fill = Brushes.LightPink;
                    }
                }
            }

            foreach (var edge in allEdgesInPaths)
            {
                var fromPos = edge.FromNode.GetPortAbsolutePosition(edge.FromPort);
                var toPos = edge.ToNode.GetPortAbsolutePosition(edge.ToPort);

                var line = new Line
                {
                    X1 = fromPos.X,
                    Y1 = fromPos.Y,
                    X2 = toPos.X,
                    Y2 = toPos.Y,
                    Stroke = Brushes.Red,
                    StrokeThickness = 4,
                    Tag = "Highlight"
                };
                GraphCanvas.Children.Add(line);
            }
        }

        private void ClearHighlights_Click(object sender, RoutedEventArgs e)
        {
            ClearHighlights(true);
        }

        private void ClearHighlights(bool clearText = true)
        {
            var highlightLines = GraphCanvas.Children
                .OfType<Line>()
                .Where(x => x.Tag?.ToString() == "Highlight")
                .ToList();

            foreach (var line in highlightLines)
            {
                GraphCanvas.Children.Remove(line);
            }

            foreach (var kvp in _nodeVisuals)
            {
                var node = kvp.Key;
                var visual = kvp.Value;

                if (visual is Grid grid && grid.Children[0] is Shape shape)
                {
                    shape.Stroke = Brushes.Black;
                    shape.StrokeThickness = 2;
                    shape.Fill = GetNodeColor(node.Type);
                }
            }

            if (clearText)
            {
                PathResultTextBox.Text = "";
            }
        }

        private void AddNode_Click(object sender, RoutedEventArgs e)
        {
            _nodeCounter++;
            var newNode = new Node($"NewNode_{_nodeCounter}", NodeType.Process, 200 + _nodeCounter * 50, 550);
            _graph.AddNode(newNode);
            DrawNode(newNode);

            PathResultTextBox.Text += $"\n添加了节点: {newNode.Id}";
        }

        private void RemoveNode_Click(object sender, RoutedEventArgs e)
        {
            if (_graph.Nodes.Any() && _nodeCounter > 0)
            {
                var nodeToRemove = _graph.Nodes.FirstOrDefault(n => n.Id == $"NewNode_{_nodeCounter}");
                if (nodeToRemove != null)
                {
                    _graph.RemoveNode(nodeToRemove);

                    if (_nodeVisuals.TryGetValue(nodeToRemove, out UIElement visual))
                    {
                        GraphCanvas.Children.Remove(visual);
                        _nodeVisuals.Remove(nodeToRemove);
                    }

                    var allEdges = GraphCanvas.Children.OfType<Line>().Where(l => l.Tag?.ToString() != "Highlight").ToList();
                    foreach (var edgeLine in allEdges)
                    {
                        GraphCanvas.Children.Remove(edgeLine);
                    }
                    foreach (var edge in _graph.Edges)
                    {
                        DrawEdge(edge);
                    }


                    PathResultTextBox.Text += $"\n移除了节点: {nodeToRemove.Id}";
                    _nodeCounter--;
                }
            }
            else
            {
                PathResultTextBox.Text += "\n没有可移除的新节点。";
            }
        }
    }

}





















        
        
        
        //public MainWindow()
        //{
        //    InitializeComponent();
        //}
    //    private Graph graph = new Graph();
    //    private List<(List<string> Path, double Weight)> allPathsWithWeight = new List<(List<string>, double)>();

    //    public MainWindow()
    //    {
    //        InitializeComponent();
    //        LoadSampleData();
    //        DrawGraph();
    //    }

    //    private void LoadSampleData()
    //    {
    //        var terminals = new List<Terminal>
    //        {
    //            new Terminal { Name = "A", ConnectedTo = "B", Weight = 2.0 },
    //            new Terminal { Name = "B", ConnectedTo = "C", Weight = 3.0 },
    //            new Terminal { Name = "C", ConnectedTo = "D", Weight = 1.0 },
    //            //new Terminal { Name = "D", ConnectedTo = "A", Weight = 4.0 },
    //            new Terminal { Name = "C", ConnectedTo = "E", Weight = 2.5 },
    //            new Terminal { Name = "A", ConnectedTo = "E", Weight = 5.0 },
    //            new Terminal { Name = "B", ConnectedTo = "E", Weight = 1.5 }
    //        };

    //        graph.BuildFromTerminals(terminals);
    //    }

    //    private void DrawGraph()
    //    {
    //        GraphCanvas.Children.Clear();

    //        // 绘制边（在节点之前，让节点覆盖在边上）
    //        foreach (var edge in graph.Edges)
    //        {
    //            var fromPt = graph.Nodes[edge.From].Position;
    //            var toPt = graph.Nodes[edge.To].Position;

    //            var line = new Line
    //            {
    //                X1 = fromPt.X,
    //                Y1 = fromPt.Y,
    //                X2 = toPt.X,
    //                Y2 = toPt.Y,
    //                Stroke = Brushes.Gray,
    //                StrokeThickness = 2,
    //                StrokeDashArray = null
    //            };
    //            GraphCanvas.Children.Add(line);
    //            edge.Visual = line;

    //            // 可选：在边中间显示权重
    //            var midX = (fromPt.X + toPt.X) / 2;
    //            var midY = (fromPt.Y + toPt.Y) / 2;

    //            var weightLabel = new TextBlock
    //            {
    //                Text = edge.Weight.ToString("F1"),
    //                FontSize = 10,
    //                Foreground = Brushes.DarkGray,
    //                Background = Brushes.Transparent
    //            };
    //            Canvas.SetLeft(weightLabel, midX - 10);
    //            Canvas.SetTop(weightLabel, midY - 12);
    //            GraphCanvas.Children.Add(weightLabel);
    //        }

    //        // 绘制节点
    //        foreach (var node in graph.Nodes.Values)
    //        {
    //            var ellipse = new Ellipse
    //            {
    //                Width = 30,
    //                Height = 30,
    //                Fill = Brushes.LightBlue,
    //                Stroke = Brushes.Black,
    //                StrokeThickness = 2
    //            };
    //            Canvas.SetLeft(ellipse, node.Position.X - 15);
    //            Canvas.SetTop(ellipse, node.Position.Y - 15);
    //            GraphCanvas.Children.Add(ellipse);
    //            node.Visual = ellipse;

    //            var label = new TextBlock
    //            {
    //                Text = node.Id,
    //                FontSize = 14,
    //                FontWeight = FontWeights.Bold,
    //                Foreground = Brushes.Black,
    //                HorizontalAlignment = HorizontalAlignment.Center
    //            };
    //            Canvas.SetLeft(label, node.Position.X - 8);
    //            Canvas.SetTop(label, node.Position.Y - 28);
    //            GraphCanvas.Children.Add(label);
    //        }
    //    }

    //    private void FindPathsButton_Click(object sender, RoutedEventArgs e)
    //    {
    //        string start = StartNodeBox.Text.Trim();
    //        string end = EndNodeBox.Text.Trim();

    //        if (!graph.Nodes.ContainsKey(start) || !graph.Nodes.ContainsKey(end))
    //        {
    //            MessageBox.Show("节点不存在！", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
    //            return;
    //        }

    //        allPathsWithWeight.Clear();
    //        DFS(start, end, new HashSet<string>(), new List<string>(), 0, allPathsWithWeight);

    //        if (allPathsWithWeight.Count == 0)
    //        {
    //            MessageBox.Show("未找到任何路径！", "提示", MessageBoxButton.OK, MessageBoxImage.Information);
    //            return;
    //        }

    //        // 显示路径列表
    //        ResultTextBlock.Text = "";
    //        for (int i = 0; i < allPathsWithWeight.Count; i++)
    //        {
    //            var (path, weight) = allPathsWithWeight[i];
    //            ResultTextBlock.Text += $"{i + 1}. {string.Join(" → ", path)} (总权重: {weight:F2})\n";
    //        }

    //        // 重置高亮
    //        ResetAllVisuals();

    //        // 开始动画高亮
    //        _ = VisualizeAllPathsAsync();
    //    }

    //    private void DFS(string current, string end, HashSet<string> visited, List<string> path, double currentWeight, List<(List<string>, double)> result)
    //    {
    //        visited.Add(current);
    //        path.Add(current);

    //        if (current == end)
    //        {
    //            result.Add((new List<string>(path), currentWeight));
    //        }
    //        else
    //        {
    //            foreach (var neighbor in graph.GetNeighbors(current))
    //            {
    //                if (!visited.Contains(neighbor))
    //                {
    //                    double edgeWeight = GetEdgeWeight(current, neighbor);
    //                    DFS(neighbor, end, visited, path, currentWeight + edgeWeight, result);
    //                }
    //            }
    //        }

    //        path.RemoveAt(path.Count - 1);
    //        visited.Remove(current);
    //    }

    //    private double GetEdgeWeight(string from, string to)
    //    {
    //        var edge = graph.Edges.FirstOrDefault(e =>
    //            (e.From == from && e.To == to) || (e.From == to && e.To == from));
    //        return edge?.Weight ?? 1.0;
    //    }

    //    private async Task VisualizeAllPathsAsync()
    //    {
    //        var colors = new[] { Brushes.Red, Brushes.Blue, Brushes.Green, Brushes.Purple, Brushes.Orange, Brushes.DeepPink, Brushes.Olive };
    //        int colorIndex = 0;

    //        foreach (var (path, weight) in allPathsWithWeight)
    //        {
    //            var pathColor = colors[colorIndex++ % colors.Length];
    //            await VisualizePathAsync(path, pathColor);
    //            await Task.Delay(2000); // 每条路径展示2秒
    //        }
    //    }

    //    private async Task VisualizePathAsync(List<string> path, Brush color)
    //    {
    //        for (int i = 0; i < path.Count - 1; i++)
    //        {
    //            string from = path[i];
    //            string to = path[i + 1];

    //            // 高亮边
    //            var edge = graph.Edges.FirstOrDefault(e =>
    //                (e.From == from && e.To == to) || (e.From == to && e.To == from));

    //            if (edge?.Visual != null)
    //            {
    //                edge.Visual.Stroke = color;
    //                edge.Visual.StrokeThickness = 4;
    //            }

    //            // 高亮节点
    //            if (graph.Nodes[from].Visual != null)
    //            {
    //                graph.Nodes[from].Visual.Fill = new SolidColorBrush(Colors.Yellow);
    //                graph.Nodes[from].Visual.Stroke = new SolidColorBrush(Colors.Black);
    //            }

    //            await Task.Delay(600); // 模拟“走”到下一个节点
    //        }

    //        // 高亮终点
    //        if (graph.Nodes[path.Last()].Visual != null)
    //        {
    //            graph.Nodes[path.Last()].Visual.Fill = new SolidColorBrush(Colors.Yellow);
    //        }
    //    }

    //    private void ResetHighlight_Click(object sender, RoutedEventArgs e)
    //    {
    //        ResetAllVisuals();
    //    }

    //    private void ResetAllVisuals()
    //    {
    //        // 重置边
    //        foreach (var edge in graph.Edges)
    //        {
    //            if (edge.Visual != null)
    //            {
    //                edge.Visual.Stroke = Brushes.Gray;
    //                edge.Visual.StrokeThickness = 2;
    //            }
    //        }

    //        // 重置节点
    //        foreach (var node in graph.Nodes.Values)
    //        {
    //            if (node.Visual != null)
    //            {
    //                node.Visual.Fill = Brushes.LightBlue;
    //                node.Visual.Stroke = Brushes.Black;
    //            }
    //        }
    //    }
    //}


